﻿/* Copyright 2011 Michiel Fortuin
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace sharplog
{
	/// <summary>
	/// The base class for a sender
	/// </summary>
	public abstract class Sender
	{
		/// <summary>
		/// Sends a message.
		/// </summary>
		/// <param name="data">The pre-formated message from a specific formater.</param>
		internal abstract void SendMessage(object data);
	}

	/// <summary>
	/// This sender is use UDP to sends it's messages. It expects a byte[] as a message input.
	/// </summary>
	public class SenderUdp : Sender
	{
		private UdpClient client;
		public IPEndPoint SyslogServer { get; set; }

		/// <summary>
		/// Creates a sender for syslog class
		/// </summary>
		/// <param name="local">the local endpoint from where the client must send the datagrams</param>
		/// <param name="syslogServer">the server to wich it must send its datagrams</param>
		public SenderUdp(IPEndPoint local, IPEndPoint syslogServer)
		{
			this.client = new UdpClient(local);
			this.SyslogServer = syslogServer;
		}

		/// <summary>
		/// Creates a sender for the syslog class
		/// </summary>
		/// <param name="syslogServer"></param>
		public SenderUdp(IPEndPoint syslogServer)
		{
			this.client = new UdpClient();
			this.SyslogServer = syslogServer;
		}

		~SenderUdp()
		{
			client.Close();
		}

		/// <summary>
		/// Sends a message.
		/// </summary>
		/// <remarks>This method should only be called from the syslog class</remarks>
		/// <param name="data">array with data</param>
		internal override void SendMessage(object data)
		{
			byte[] d = (byte[]) data;
			client.Send(d, d.Length, SyslogServer);
		}
	}

	/// <summary>
	/// Sender over TCP. This one expects a byte[] as a message.
	/// </summary>
	/// <remarks>
	/// This sender doesn't work yet.
	/// </remarks>
	public class SenderTcp : Sender
	{
		private TcpClient client;
		private NetworkStream s;
		public IPEndPoint SyslogServer { get; private set; }

		private void helpCtor(IPEndPoint local, IPEndPoint syslogServer)
		{
			this.client = new TcpClient(local);
			this.client.Connect(syslogServer);
			s = client.GetStream();
			this.SyslogServer = syslogServer;
		}

		public SenderTcp(IPEndPoint local, IPEndPoint syslogServer)
		{
			this.helpCtor(local, syslogServer);
		}

		public SenderTcp(IPEndPoint syslogServer)
		{
			this.helpCtor(new IPEndPoint(IPAddress.Any, 514), syslogServer);
		}

		~SenderTcp()
		{
			client.Close();
		}

		internal override void SendMessage(object data)
		{
			byte[] d = (byte[]) data;
			s.Write(d, 0, d.Length);
		}
	}
}
